﻿//morseCore.js

import { 
    MORSE_CODE_MAP, DOT_TO_DASH_RATIO, CHAR_SPACING_RATIO, 
    WORD_SPACING_RATIO, LIGHT_MODE_SCREEN, LIGHT_MODE_FLASHLIGHT,
    DEFAULT_CODE_SPEED, SPEED_WPM_RATIO
} from './constants.js';
import { calculateDotDuration } from './utils.js';

// 核心应用状态
export const state = {
    animationSequence: [],
    animationTimer: null,
    isAnimationPlaying: false,
    codeSpeed: DEFAULT_CODE_SPEED,
    lightMode: LIGHT_MODE_SCREEN,
    wakeLock: null,
    flashlightStream: null,
    get wordsPerMinute() {
        return this.codeSpeed / SPEED_WPM_RATIO;
    }
};

/**
 * 验证输入文本
 * @param {HTMLTextAreaElement} inputText - 输入框元素
 * @returns {string|null} 验证后的输入文本
 */
export function validateInput(inputText) {
    const text = inputText.value.trim();
    return text || null;
}

/**
 * 处理单个字符或符号
 * @param {string} char - 要处理的字符
 * @param {number} dotDuration - 点信号时长
 */
function processCharacter(char, dotDuration) {
    const sequence = state.animationSequence;
    
    // 处理空格（多个连续空格只算一个）
    if (char === ' ') {
        sequence.push({ state: 'dark', duration: WORD_SPACING_RATIO * dotDuration });
        return;
    }
    
    // 获取字符对应的莫尔斯码
    let morse = MORSE_CODE_MAP[char] || MORSE_CODE_MAP[char.toUpperCase()];
    
    if (morse) {
        // 处理莫尔斯码
        for (let i = 0; i < morse.length; i++) {
            const signal = morse[i];
            if (signal === '.') {
                sequence.push({ state: 'light', duration: dotDuration });
            } else if (signal === '-') {
                sequence.push({ state: 'light', duration: DOT_TO_DASH_RATIO * dotDuration });
            }
            
            // 信号间间隔（除最后一个信号外）
            if (i < morse.length - 1) {
                sequence.push({ state: 'dark', duration: dotDuration });
            }
        }
        
        // 字符后间隔
        sequence.push({ state: 'dark', duration: CHAR_SPACING_RATIO * dotDuration });
    }
}

/**
 * 生成动画序列
 * @param {string} text - 输入文本
 */
export function generateAnimation(text) {
    state.animationSequence = [];
    const dotDuration = calculateDotDuration(state.wordsPerMinute);
    let i = 0;
    
    while (i < text.length) {
        if (text[i] === '[') {
            const endIndex = text.indexOf(']', i);
            if (endIndex !== -1) {
                const symbol = text.substring(i, endIndex + 1);
                processCharacter(symbol, dotDuration);
                i = endIndex + 1;
                continue;
            }
        }
        
        processCharacter(text[i], dotDuration);
        i++;
    }
}

/**
 * 初始化闪光灯
 * @returns {Promise<boolean>} 是否初始化成功
 */
export async function initializeFlashlight() {
    try {
        const constraints = {
            video: {
                facingMode: 'environment',
                advanced: [{ torch: false }]
            }
        };
        
        const stream = await navigator.mediaDevices.getUserMedia(constraints);
        const track = stream.getVideoTracks()[0];
        
        if (!track.getCapabilities().torch) {
            throw new Error('Flashlight not available');
        }
        
        // 保存流引用以便后续控制
        state.flashlightStream = stream;
        return true;
    } catch (error) {
        console.error('闪光灯初始化错误:', error);
        return false;
    }
}

/**
 * 控制闪光灯状态
 * @param {string} stateValue - 状态 ('light' 或 'dark')
 */
export async function controlFlashlight(stateValue) {
    try {
        if (state.lightMode !== LIGHT_MODE_FLASHLIGHT) return;
        
        if (!state.flashlightStream) {
            await initializeFlashlight();
        }
        
        const track = state.flashlightStream.getVideoTracks()[0];
        if (track) {
            await track.applyConstraints({ advanced: [{ torch: stateValue === 'light' }] });
        }
    } catch (error) {
        console.error('闪光灯控制错误:', error);
        state.lightMode = LIGHT_MODE_SCREEN;
        throw new Error('闪光灯控制失败，已切换为屏幕模式');
    }
}

/**
 * 插入勤务符号
 * @param {HTMLTextAreaElement} inputText - 输入框元素
 * @param {string} symbol - 勤务符号
 */
export function insertSpecialSymbol(inputText, symbol) {
    const cursorPos = inputText.selectionStart;
    const text = inputText.value;
    
    let newText = '';
    let newCursorPos = cursorPos;
    
    if (symbol === '[CALL]') {
        newText = text.substring(0, cursorPos) + '[CALL]' + text.substring(cursorPos);
        newCursorPos = cursorPos + 6;
        if (newText[newCursorPos] !== ' ') {
            newText = newText.substring(0, newCursorPos) + ' ' + newText.substring(newCursorPos);
            newCursorPos++;
        }
    } else if (symbol === '[END]') {
        let prefix = '';
        if (cursorPos > 0 && text[cursorPos - 1] !== ' ') {
            prefix = ' ';
        }
        newText = text.substring(0, cursorPos) + prefix + '[END]' + text.substring(cursorPos);
        newCursorPos = cursorPos + prefix.length + 5;
    }
    
    inputText.value = newText;
    inputText.focus();
    inputText.setSelectionRange(newCursorPos, newCursorPos);
}

/**
 * 请求屏幕唤醒锁
 */
export async function requestWakeLock() {
    try {
        if ('wakeLock' in navigator) {
            state.wakeLock = await navigator.wakeLock.request('screen');
            console.log('屏幕唤醒锁已激活');
            
            state.wakeLock.addEventListener('release', () => {
                console.log('屏幕唤醒锁已释放');
            });
        }
    } catch (err) {
        console.error(`无法获取屏幕唤醒锁: ${err.message}`);
    }
}

/**
 * 释放屏幕唤醒锁
 */
export function releaseWakeLock() {
    if (state.wakeLock !== null) {
        state.wakeLock.release();
        state.wakeLock = null;
    }
}
